import jsonpath
import requests
import urllib3


urllib3.disable_warnings()


class Auth:
    AUTH_TYPE = ''

    def __init__(self, value):
        self.value = value

    def generate(self):
        pass


class NoneAuth(Auth):
    """免密码"""
    AUTH_TYPE = 'none'

    def __init__(self, **ignore_kwargs):
        super().__init__(value=None)


class StaticAuth(Auth):
    """固定TOKEN"""
    AUTH_TYPE = 'static'

    def __init__(self, value, **ignore_kwargs):
        super().__init__(value=value)


class DynamicAuth(Auth):
    """动态生成TOKEN"""
    AUTH_TYPE = 'dynamic'

    def __init__(self, request, where, expr, value=None, prefix='', **ignore_kwargs):
        self.request = request
        self.expr = expr
        self.where = where
        self.prefix = prefix
        super().__init__(value=value)

    def generate(self):
        _resp = API(**self.request).call()
        obj = _resp.get(self.where, {})
        matcher = jsonpath.jsonpath(obj, expr=self.expr)
        if not matcher:
            raise Exception('未提取到动态密码')
        self.value = f'{self.prefix}{matcher[0]}'


auth_processor = {sub.AUTH_TYPE: sub for sub in Auth.__subclasses__()}


class API:

    def __init__(self, url, method='GET', timeout=90, **kwargs):
        self.url = url
        self.method = method
        self.timeout = timeout
        self.kwargs = kwargs

    def call(self):
        kwargs = {'timeout': self.timeout, 'verify': False, **self.kwargs}
        resp = requests.request(self.method, self.url, **kwargs)
        if resp.headers.get('Content-Type') == 'application/json':
            return {'data': resp.json(), 'headers': dict(resp.headers)}
        return {'data': resp.text, 'headers': dict(resp.headers)}


class APICollect:
    """api采集"""
    def __init__(self, config):
        self.config = config

    def _auth(self):
        auth_config = self.config.get('auth', {})

        auth_ins = auth_processor[auth_config['type']](**auth_config)
        auth_ins.generate()
        if not auth_ins.value:
            return

        # 请求中添加token
        where = auth_config.get('token', {}).get('where', 'headers')
        key = auth_config.get('token', {}).get('key', 'Authorization')

        where_data = self.config['request'].get(where, {})
        self.config['request'][where] = {key: auth_ins.value, **where_data}

    def collect(self):
        self._auth()
        _res = API(**self.config['request']).call()
        return _res


if __name__ == '__main__':
    na = NoneAuth().value
    sa = StaticAuth('aa').value
    da = DynamicAuth(
        request=dict(url='https://192.168.101.79/sysmgmt/api/v1/auth/login?dom_ctx=Default&app_context=_la&domain=default',
                            method='POST',
                            json={"account": "admin", "password":"ZdUq9LEEUI7C3SweMtKw5X2/woJukQQ8eCuDX08+m1PHGJl0qjG0VI6KMDahpkC4XesiV1EgKjCOg4Bjvi6wW0tWLIzebwrGuF8rlaPbEnmiK7o738te/JswfY7gREWoo71xq6oUW75wulDoksQJWFy02kzzrhYg+SMqe8r8XBs="}),
        where='data', expr='access_token')
    da.generate()
    da_v = da.value

    r1 = API('https://192.168.101.79/').call()
    r2 = API(url='https://192.168.101.79/sysmgmt/api/v1/auth/login?dom_ctx=Default&app_context=_la&domain=default',
             method='POST',
             data='''{"account": "admin",
                   "password":"ZdUq9LEEUI7C3SweMtKw5X2/woJukQQ8eCuDX08+m1PHGJl0qjG0VI6KMDahpkC4XesiV1EgKjCOg4Bjvi6wW0tWLIzebwrGuF8rlaPbEnmiK7o738te/JswfY7gREWoo71xq6oUW75wulDoksQJWFy02kzzrhYg+SMqe8r8XBs="}''').call()

    r3 = APICollect(
        config={
            'auth': {'type': 'none'},
            'request': dict(
                    url='https://192.168.101.79/sysmgmt/api/v1/license/get?verify=true&dom_ctx=Default&app_context=_la&domain=default',
                    method='GET')
        }
    ).collect()
    r3_ = APICollect(
        config={
            'auth': {'type': 'none'},
            'request': dict(
                    url='https://192.168.101.79/sysmgmt/api/v1/license/get?verify=true&dom_ctx=Default&app_context=_la&domain=default',
                    method='GET',
                    headers={'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJlMDJhYTg4YzliYzc3NzZhMzgyMTA1MWNhMjM4N2M5NyIsImV4cCI6MTczOTM3MzAzMn0.7n0wZ2HsdKZwJewJzoQ-J2TW1592o5SH59ZMzRlarGQ'}
            )
        }
    ).collect()

    r4 = APICollect(
        config={
            'auth': {
                'type': 'static',
                'value': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJlMDJhYTg4YzliYzc3NzZhMzgyMTA1MWNhMjM4N2M5NyIsImV4cCI6MTczOTM3MzAzMn0.7n0wZ2HsdKZwJewJzoQ-J2TW1592o5SH59ZMzRlarGQ',
                'token': {'where': 'headers', 'key': 'authorization'}
            },
            'request': dict(
                    url='https://192.168.101.79/sysmgmt/api/v1/license/get?verify=true&dom_ctx=Default&app_context=_la&domain=default',
                    method='GET')
        }
    ).collect()

    r5 = APICollect(
        config={
            'auth': {
                'type': 'dynamic',
                'request': dict(
                    url='https://192.168.101.79/sysmgmt/api/v1/auth/login?dom_ctx=Default&app_context=_la&domain=default',
                    method='POST',
                    data='{"account": "admin", "password":"ZdUq9LEEUI7C3SweMtKw5X2/woJukQQ8eCuDX08+m1PHGJl0qjG0VI6KMDahpkC4XesiV1EgKjCOg4Bjvi6wW0tWLIzebwrGuF8rlaPbEnmiK7o738te/JswfY7gREWoo71xq6oUW75wulDoksQJWFy02kzzrhYg+SMqe8r8XBs="}'.encode()),
                'where': 'data', 'expr': 'access_token', 'prefix': 'Bearer ',
                'token': {'where': 'headers', 'key': 'authorization'}
            },
            'request': dict(
                    url='https://192.168.101.79/sysmgmt/api/v1/license/get?verify=true&dom_ctx=Default&app_context=_la&domain=default',
                    method='GET')
        }
    ).collect()

    print('todo')
